home *** CD-ROM | disk | FTP | other *** search
/ MacWorld: Conference & Expo 2005 / Macworld Conference and Expo - Documentation CD-ROM (2004).iso / mac / Adobe Reader 6.0 / Adobe Reader 6.0.app / Contents / MacOS / JavaScripts / debugger.js < prev    next >
Text File  |  2004-01-30  |  19KB  |  685 lines

  1. /*
  2.     ==========================================================================
  3.     Module: debugger.js
  4.     ==========================================================================
  5.     JS functionality for JavaScript Debugger.
  6.     ==========================================================================
  7.     The Software, including this file, is subject to the End User License
  8.     Agreement.
  9.     Copyright (c) 1998-2002, Adobe Systems Incorporated, All Rights Reserved.
  10.     ==========================================================================
  11. */
  12.  
  13. // The following code "exports" any strings in the list into the current scope.
  14. var msgStrings = new Array(
  15.     "IDS_STARTUP_DEBUGGER_MSG",
  16.     "IDS_INVALID_BREAKPOINT", 
  17.     "IDS_EXCEPTION_INLINE",
  18.     "IDS_UNABLE_FINDSOURCE",
  19.     "IDS_TOP_LEVEL",
  20.     "IDS_INVALID_BPLINE",
  21.     "IDS_STACK_STRING",
  22.     "IDS_CANNOT_EVALWATCH");
  23.  
  24. for(var n = 0; n < msgStrings.length; n++)
  25.     eval(msgStrings[n] + " = " + getString({cPlugInName: "EScript", cStringId: msgStrings[n]}).toSource());
  26.  
  27. printConsole(IDS_STARTUP_DEBUGGER_MSG+"\n");
  28.  
  29. /***************************************************************************/
  30. /* Hook functions */
  31.  
  32. var debugVerbose = false;
  33.  
  34. var jsStack = null;
  35. var hookType;
  36. var currentFrame;
  37. var resumeCode = 1;
  38. var stepType = -1;
  39.  
  40. var startPC = 0;
  41. var startLineno = 0;
  42. var startFrame = 0;
  43. var startFileName = "";
  44. var startFunname = "";
  45.  
  46. var curProps = null;
  47. var curScript = null;
  48.  
  49. var bpCreate = true;
  50.  
  51. const TMODE_IGNORE = 0;
  52. const TMODE_TRACE = 1;
  53. const TMODE_BREAK = 2;
  54.  
  55. const PROTOTYPE = "[[Prototype]]";
  56. const PARENT = "[[Parent]]";
  57. const FOLDER_LEVEL = "Folder-Level";
  58.  
  59. jsd.SetScriptHook(scriptHook);
  60. jsd.SetExecutionHook(execHook);
  61.  
  62. function stepNext() {
  63.     return (jsStack[0].pc < startPC && jsStack[0].lineno != startLineno || jsStack[0].lineno > startLineno);
  64. }
  65.  
  66. function shouldStop() {
  67.     // In case we've hit an exception.
  68.     if (hookType == jsd.JSD_HOOK_THROW) {
  69.         var tMode = getThrowMode();
  70.         switch (tMode) {
  71.             case TMODE_IGNORE:
  72.                 return false;
  73.                 break;
  74.             case TMODE_TRACE:
  75.             case TMODE_BREAK:
  76.                 var displayString = IDS_EXCEPTION_INLINE.replace('%d', jsStack[0].lineno);
  77.                 displayString = displayString.replace('%s', jsStack[0].script.funName);
  78.                 displayString = displayString.replace('%s', jsStack[0].script.fileName);
  79.                 printConsole(displayString);
  80.                 return tMode == TMODE_BREAK ? true : false;
  81.                 break;
  82.             default:
  83.                 return false;
  84.         }
  85.     }
  86.  
  87.     // if we reach hook due to an interrupt, it's probably a step.
  88.     if (hookType == jsd.JSD_HOOK_INTERRUPTED) {
  89.         switch (stepType) {
  90.             case 0: // Step Byte Code
  91.                 return true;
  92.             break;
  93.             case 1: // Step Into
  94.                 return (jsStack[0].script.fileName != startFileName || 
  95.                         jsStack[0].script.funName != startFunname) ? true : stepNext();
  96.             break;
  97.             case 2: // Step Over
  98.                 return (jsStack.length-1 <= startFrame) ? stepNext() : false;
  99.             break;
  100.             case 3: // Step Out (of function)
  101.             {
  102.                    if (debugVerbose)
  103.                      printConsole("condition: "+(jsStack.length-1 < startFrame)+" stepNext: "+stepNext()+"\n");
  104.                 return (jsStack.length-1 < startFrame) ? stepNext() : false;
  105.             }
  106.             break;
  107.             default: // This in case interrupt button is on, but we're not stepping.
  108.                 return true;
  109.             break;
  110.         }
  111.     }
  112.  
  113.     // make sure we're not stepping.
  114.     if (stepType == -1) {
  115.         // if we reach hook due to a breakpoint, it's a breakpoint.
  116.         if (hookType == jsd.JSD_HOOK_BREAKPOINT) {
  117.             var bpIndex = getBPIndex(jsStack[0].script.fileName, jsStack[0].lineno);
  118.             if (bpIndex != -1) {
  119.                 var ret = debugEval(breakpoints[bpIndex].condition);
  120.                    if (debugVerbose)
  121.                     printConsole(breakpoints[bpIndex].condition+": "+ ret +"\n");
  122.  
  123.                 if (ret == "true") {
  124.                        if (debugVerbose)
  125.                         printConsole(typeof(ret) + ": Ok\n");
  126.                     return true;
  127.                 }
  128.             }
  129.         }
  130.  
  131.         // if we reach hook due to "debugger keyword", it's a breakpoint.
  132.         if (hookType == jsd.JSD_HOOK_DEBUGGER_KEYWORD)
  133.             return true;
  134.     }
  135.  
  136.     // No, we're not going to stop.
  137.     return false;
  138. }
  139.  
  140. function GetTextFromFilename(filename) {
  141.     var handle = jsd.FindSourceForURL(filename);
  142.     if (handle == null)
  143.         return printConsole(IDS_UNABLE_FINDSOURCE.replace('%s', filename));
  144.  
  145.     return jsd.GetSourceText(handle);
  146. }
  147.  
  148. function execHook(type) {
  149.     /* we reset these globals. hookType is reason for stoping. */
  150.     jsStack = null;
  151.     currentFrame = 0;
  152.     hookType = type;
  153.     buildStack();
  154.  
  155.        if (debugVerbose) {
  156.          printConsole("hookType: "+hookType+" stepType: "+stepType+"\n");
  157.          printConsole("lineno: "+jsStack[0].lineno+" fileName: "+jsStack[0].script.fileName+"\n");
  158.     }
  159.  
  160.     if (shouldStop()) {
  161.         openDebugger();
  162.  
  163.            unsuspend();
  164.  
  165.         // reset these.
  166.         resumeCode = -1;
  167.         stepType = -1;
  168.  
  169.         selectScriptLine(jsStack[0].lineno, jsStack[0].script.fileName, "", 0);
  170.         suspendThread();
  171.  
  172.            if (debugVerbose)
  173.              printConsole("resumeCode: "+resumeCode+"\n");
  174.  
  175.         return resumeCode;
  176.     }
  177.  
  178.     return jsd.JSD_HOOK_RETURN_CONTINUE;
  179. }
  180.  
  181. function scriptHook(handle, creating) {
  182.     if (creating) {
  183.         JSDScript.add(new JSDScript(handle,
  184.                                     jsd.GetScriptFilename(handle),
  185.                                     jsd.GetScriptFunctionName(handle),
  186.                                     jsd.GetScriptBaseLineNumber(handle),
  187.                                     jsd.GetScriptLineExtent(handle)));
  188.         setAllBreakpointsForScript(handle);
  189.     } else {
  190.         JSDScript.remove(JSDScript.find(handle));
  191.     }
  192.     return true;
  193. }
  194.  
  195. /***************************************************************************/
  196. /* JSDScript Object */
  197.  
  198. function JSDScript(handle, fileName, funName, base, extent) {
  199.     this.handle = handle;
  200.     this.fileName = fileName;
  201.     this.funName = (funName != null && funName.length ? funName : IDS_TOP_LEVEL);
  202.     this.base = base;
  203.     this.extent = extent;
  204.     this.toString = function() {return (funName != null && funName.length ? funName : IDS_TOP_LEVEL)}
  205.     if (debugVerbose)
  206.         printConsole(fileName + ":" + base  + ":" + extent +"\n");
  207. }
  208.  
  209. JSDScript.scripts = new Object;
  210.  
  211. JSDScript.add = function(script) {
  212.     JSDScript.scripts[script.handle] = script;
  213.     addPCMap(script);
  214.  
  215. /* use this to see the final pcMap on the console
  216.        if (script.toString() == "top_level" && script.fileName == "Folder-Level:App:aform.js") 
  217.     {
  218.         var filePCMap = findPCMap(script);
  219.         for (var i = 0; i < Math.min(150, filePCMap.exec.length); i++)
  220.             printConsole(i + ":" + filePCMap.exec[i] +"\n");
  221.     }
  222. */
  223. }
  224.  
  225. JSDScript.remove = function(script) {
  226.     if (script) {
  227.            if (debugVerbose)
  228.             printConsole(script.fileName + ":" + script.funName +"\n");
  229.         delete JSDScript.scripts[script.handle];
  230.         if (script.fileName.substr(0, FOLDER_LEVEL.length) != FOLDER_LEVEL)
  231.             deletePCMap(script);
  232.     }
  233. }
  234.  
  235. JSDScript.find = function(handle) {
  236.     return JSDScript.scripts[handle];
  237. }
  238.  
  239. /***************************************************************************/
  240. /* PCMaps Array */
  241.  
  242. var scriptPCMaps = new Array;
  243.  
  244. function filePCMap(fileName) {
  245.     this.fileName = fileName;
  246.     this.exec = new Array();
  247. }
  248.  
  249. function findPCMapFromFilename(fileName) {
  250.     for(var i = 0; i < scriptPCMaps.length; i++) {
  251.         if (scriptPCMaps[i].fileName == fileName)
  252.             return scriptPCMaps[i];
  253.     }
  254.     return null;
  255. }
  256.  
  257. function findPCMap(script) {
  258.     var pcMap = findPCMapFromFilename(script.fileName);
  259.     if (!pcMap) {
  260.         pcMap = new filePCMap(script.fileName);
  261.         scriptPCMaps.push(pcMap);
  262.     }
  263.  
  264.     return pcMap;
  265. }
  266.  
  267. function addPCMap(script) {
  268.     var filePCMap = findPCMap(script);
  269.     for(var i = script.base; i < script.base+script.extent; i++) {
  270.         var line = jsd.GetClosestLine(script.handle, jsd.GetClosestPC(script.handle, i));
  271.         filePCMap.exec[i] = filePCMap.exec[i] || (i == line) ? true : false;
  272.         if (debugVerbose)
  273.             printConsole(i + ":" + filePCMap.exec[i] +"\n");
  274.     }
  275. }
  276.  
  277. function deletePCMap(script) {
  278.     for(var i = 0; i < scriptPCMaps.length; i++) {
  279.         if (scriptPCMaps[i].fileName == script.fileName) {
  280.             delete scriptPCMaps[i];
  281.             scriptPCMaps.splice(i, 1);
  282.             return;
  283.         }
  284.     }
  285. }
  286.  
  287. function canSetBreakpoint(fileName, lineNum) {
  288.     var pcMap = findPCMapFromFilename(fileName);
  289.     if (pcMap != undefined)
  290.         return pcMap.exec[lineNum];
  291.  
  292.     return true;
  293. }
  294.  
  295. function pcMapExists(fileName) {
  296.     if (findPCMapFromFilename(fileName))
  297.         return true;
  298.     return false;
  299. }
  300.  
  301. /***************************************************************************/
  302. /* JSDFrame (jsStack) Object */
  303.  
  304. function JSDFrame(handle) {
  305.     this.handle = handle;
  306.     this.script = JSDScript.find(jsd.GetScriptForStackFrame(handle));
  307.     this.pc = jsd.GetPCForStackFrame(handle);
  308.     this.lineno = jsd.GetClosestLine(this.script.handle, this.pc);
  309. }
  310.  
  311. function buildStack() {
  312.     var count = jsd.GetCountOfStackFrames();
  313.  
  314.     jsStack = new Array(count);
  315.     jsStack[0] = new JSDFrame(jsd.GetStackFrame());
  316.     for(var i = 0; i < count-1; i++)
  317.         jsStack[i+1] = new JSDFrame(jsd.GetCallingStackFrame(jsStack[i].handle));
  318. }
  319.  
  320. /***************************************************************************/
  321. /* JSDProperty Object */
  322.  
  323. function JSDProperty(propValue, readOnly) {
  324.     this.value = propValue;
  325.     this.type = (jsd.IsValueObject(propValue)  ? "o" : "") +
  326.                 (jsd.IsValueInt(propValue)       ? "i" : "") +
  327.                 (jsd.IsValueDouble(propValue)  ? "d" : "") +
  328.                 (jsd.IsValueString(propValue)  ? "s" : "") +
  329.                 (jsd.IsValueBoolean(propValue) ? "b" : "") +
  330.                 (jsd.IsValueVoid(propValue)       ? "u" : "") +
  331.                 (readOnly                       ? "r" : "w");
  332.     this.valString = jsd.GetValueString(propValue);
  333. //    this.count = jsd.GetCountOfProperties(propValue);
  334. }
  335.  
  336. /***************************************************************************/
  337. /* JSDValue Object */
  338.  
  339. function JSDValue(handle) {
  340.     if (!handle)
  341.         return null;
  342.  
  343.     this.handle = handle;
  344.     this.a = new Array();
  345.     this.GetPropNames = function() {return this.a;}
  346.     this.GetProperties = function() {
  347.         var o = new Object();
  348.         jsd.IterateProperties(this.handle, cb, o, this.a);
  349.  
  350.         if (jsd.GetValueClassName(this.handle) != "Array")
  351.             this.a.sort();
  352.  
  353.         var protoValue = jsd.GetValuePrototype(this.handle);
  354.         if (protoValue) {
  355.             o[PROTOTYPE] = new JSDProperty(protoValue, true);
  356.             this.a.unshift(PROTOTYPE);
  357.         }
  358.         var parentValue = jsd.GetValueParent(this.handle);
  359.         if (parentValue) {
  360.             o[PARENT] = new JSDProperty(parentValue, true);
  361.             this.a.unshift(PARENT);
  362.         }
  363.  
  364.         return o;
  365.     }
  366.  
  367.     function cb(ob, prop, o, a) {
  368.         var propValue = jsd.GetPropertyValue(prop);
  369.         if (!jsd.IsValueFunction(propValue)) {
  370.             var propName = jsd.GetValueString(jsd.GetPropertyName(prop));
  371.             if (propName != "__privateErase") {
  372.                 o[propName] = new JSDProperty(propValue, (jsd.GetPropertyFlags(prop) & jsd.JSDPD_READONLY));
  373.                 a.push(propName);
  374. //               if (debugVerbose)
  375. //                    printConsole(propName+":"+jsd.GetValueString(propValue)+"\n");
  376.             }
  377.         }
  378.         return true;
  379.     }
  380. }
  381.  
  382. /***************************************************************************/
  383. /* Breakpoints */
  384.  
  385. breakpoints = new Array();
  386.  
  387. function enumBreakpoints() {
  388.     for(var i = 0; i < breakpoints.length; i++)
  389.         regBreakpoint(i, breakpoints[i].fileName, breakpoints[i].lineNum, breakpoints[i].condition);
  390. }
  391.  
  392. function setBreakpoints(pddHandle, bpArray) {
  393.     for(var i = 0; i < bpArray.length; i++) {
  394.         var fileName = bpArray[i].fileName;
  395.         if (fileName.substr(fileName.length - 3) != ".js")
  396.             setBreakpoint(pddHandle, fileName, bpArray[i].lineNum, bpArray[i].condition);
  397.     }
  398. }
  399.  
  400. function Breakpoint(pddHandle, fileName, lineNum, condition) {
  401.     this.pddHandle = pddHandle;
  402.     this.fileName = fileName;
  403.     this.lineNum = lineNum;
  404.     this.condition = condition;
  405.     this.isSet = false;
  406. }
  407.  
  408. function getBPIndex(fileName, lineNum) {
  409.     for(var i = 0; i < breakpoints.length; i++)
  410.         if (breakpoints[i].fileName == fileName && breakpoints[i].lineNum == lineNum)
  411.             return i;
  412.     return -1;
  413. }
  414.  
  415. function bpCallback(handle, fileName, lineno, set) {
  416.     var script = JSDScript.find(handle);
  417.     if (script && script.fileName == fileName) {
  418.         if (script.base <= lineno && script.base+script.extent > lineno)
  419.         {
  420.             var pc = jsd.GetClosestPC(handle, lineno);
  421.             if (lineno == jsd.GetClosestLine(handle, pc)) {
  422.                 set ? jsd.SetTrap(handle, pc) : jsd.ClearTrap(handle, pc);
  423.                 bpCreate = true;
  424. //                printConsole((set ? "set" : "clear") + fileName +"\n");
  425.                 return false; // if iterating, stop, as we found bp.
  426.             }
  427.         } else {
  428.             bpCreate = false;
  429.         }
  430.     }
  431.  
  432.     return true;
  433. }
  434.  
  435. function setAllBreakpointsForScript(handle) {
  436.     for(var i = 0; i < breakpoints.length; i++) {
  437.         bpCreate = false;
  438.         bpCallback(handle, breakpoints[i].fileName, breakpoints[i].lineNum, true);
  439.         if (bpCreate)
  440.             breakpoints[i].isSet = true;
  441.     }
  442.  
  443.     var script = JSDScript.find(handle);
  444.     if (script.funName == "") {
  445.         for(var i = 0; i < breakpoints.length; i++) {
  446.             if (breakpoints[i].fileName == script.fileName && !breakpoints[i].isSet) {
  447.                 var displayString = IDS_INVALID_BPLINE.replace('%d', breakpoints[i].lineNum);
  448.                 displayString = displayString.replace('%s', breakpoints[i].fileName);
  449.                 printConsole(displayString);
  450.                 updateBreakpoint(false, breakpoints[i].lineNum, i, breakpoints[i].fileName, breakpoints[i].condition);
  451.                 delete breakpoints[i];
  452.                 breakpoints.splice(i, 1);
  453.                 i--;
  454.             }
  455.         }
  456.     }
  457. }
  458.  
  459. function setBreakpoint(pddHandle, fileName, lineNum, condition) {
  460.     bpCreate = canSetBreakpoint(fileName, lineNum);
  461.     if (bpCreate) {
  462.         var bpIndex = getBPIndex(fileName, lineNum);
  463.         if (bpIndex == -1) {
  464.                jsd.IterateScripts(bpCallback, fileName, lineNum, true);
  465.             var theCondition = (condition == undefined) ? "true" : condition;
  466.             breakpoints[breakpoints.length] = new Breakpoint(pddHandle, fileName, lineNum, theCondition);
  467.             updateBreakpoint(true, lineNum, breakpoints.length-1, fileName, theCondition);
  468.             saveBreakpoints();
  469.         }
  470.         if (debugVerbose)
  471.             printConsole("breakpoint set at line "+pddHandle+" of "+fileName+"\n");
  472.     } else {
  473.         var displayString = IDS_INVALID_BREAKPOINT.replace('%d', lineNum);
  474.         displayString = displayString.replace('%s', fileName);
  475.         displayAlert(displayString);
  476.     }
  477. }
  478.  
  479. function clearBreakpoint(fileName, lineNum) {
  480.     var bpIndex = getBPIndex(fileName, lineNum);
  481.     if (bpIndex != -1) {
  482.         jsd.IterateScripts(bpCallback, fileName, lineNum, false);
  483.         delete breakpoints[bpIndex];
  484.         breakpoints.splice(bpIndex, 1);
  485.         updateBreakpoint(false, lineNum, bpIndex, fileName, "");
  486.         saveBreakpoints();
  487.     }
  488.     if (debugVerbose)
  489.         printConsole("breakpoint cleared at line "+lineNum+" of "+fileName+"\n");
  490. }
  491.  
  492. function clearBreakpointsForDoc(pddHandle) {
  493.     for(var i = 0; i < breakpoints.length; i++) {
  494.         if (breakpoints[i].pddHandle == pddHandle) {
  495.             updateBreakpoint(false, breakpoints[i].lineNum, i, breakpoints[i].fileName, breakpoints[i].condition);
  496.             delete breakpoints[i];
  497.             breakpoints.splice(i, 1);
  498.             i--;
  499.         }
  500.     }
  501. }
  502.  
  503. function toggleBreakpoint(pddHandle, fileName, lineNum, condition) {
  504.     var bpIndex = getBPIndex(fileName, lineNum);
  505.     if (bpIndex == -1)
  506.         setBreakpoint(pddHandle, fileName, lineNum, condition);
  507.     else
  508.         clearBreakpoint(fileName, lineNum);
  509. }
  510.  
  511. function updateBreakpointsForScript(fileName) {
  512.     for(var i = 0; i < breakpoints.length; i++) {
  513.         if (breakpoints[i].fileName == fileName)
  514.             updateBreakpoint(true, breakpoints[i].lineNum, i, fileName, breakpoints[i].condition);
  515.     }
  516. }
  517.  
  518. function changeBPCondition(i, newCondition) {
  519.     if (i >= 0 && i < breakpoints.length && newCondition) {
  520.         breakpoints[i].condition = newCondition;
  521.         updateBreakpoint(true, breakpoints[i].lineNum, i, breakpoints[i].fileName, breakpoints[i].condition);
  522.         saveBreakpoints();
  523.     }
  524. }
  525.  
  526. /***************************************************************************/
  527. /* JSDebugger dialog uses this API. */
  528.  
  529. function unsuspend() {
  530.     if (jsd.InterruptSet) {
  531.         jsd.ClearInterrupt();
  532.         updateStopIcon();
  533.     }
  534. }
  535.  
  536. function suspend() {
  537.     if (!jsd.InterruptSet) {
  538.         jsd.SendInterrupt();
  539.         updateStopIcon();
  540.     }
  541. }
  542.  
  543. function isInterruptSet() {
  544.     return jsd.InterruptSet;
  545. }
  546.  
  547. function step(type) {
  548.     if (jsStack) {
  549.         stepType = type;
  550.  
  551.         /* frame for step is always 0. */
  552.         startPC = jsStack[0].pc;
  553.         startLineno = jsStack[0].lineno;
  554.         startFileName = jsStack[0].script.fileName;
  555.         startFunname = jsStack[0].script.funName;
  556.         startFrame = jsStack.length-1;
  557.  
  558.         suspend();
  559.            resume();
  560.     }
  561. }
  562.  
  563. function quit() {
  564.     clearStack();
  565.     clearInspector();
  566.     curProps = null;
  567.     curScript = null;
  568.  
  569.     unsuspend();
  570.     stepType = -1;
  571.  
  572.     resume(jsd.JSD_HOOK_RETURN_HOOK_ERROR);
  573. }
  574.  
  575. function resume(code) {
  576.     if (arguments.length &&
  577.         code >= jsd.JSD_HOOK_RETURN_HOOK_ERROR &&
  578.         code <= jsd.JSD_HOOK_RETURN_CONTINUE_THROW) {
  579.         resumeCode = code;
  580.     } else {
  581.         if (hookType == jsd.JSD_HOOK_THROW)
  582.             resumeCode = jsd.JSD_HOOK_RETURN_CONTINUE_THROW;
  583.         else
  584.             resumeCode = jsd.JSD_HOOK_RETURN_CONTINUE;
  585.     }
  586. }
  587.  
  588. function listRecursive(bThis) {
  589.     if (jsStack) {
  590.         if (jsStack[currentFrame].script.toString() != curScript)
  591.             clearInspector();
  592.         var callObjHandle = bThis ? jsd.GetThisForStackFrame(jsStack[currentFrame].handle) : 
  593.                                     jsd.GetScopeChainForStackFrame(jsStack[currentFrame].handle);
  594.         displayRecursive(false, callObjHandle);
  595.         curScript = jsStack[currentFrame].script.toString();
  596.     }
  597. }
  598.  
  599. function displayRecursive(isNode, callObjHandle) {
  600.     if (callObjHandle) {
  601.         var callObj = new JSDValue(callObjHandle);
  602.         if (callObj) {
  603.             var props = callObj.GetProperties();
  604.             if (props) {
  605.                 var namesArray = callObj.GetPropNames();
  606.  
  607.                 for(var i = 0; i < namesArray.length; i++) {
  608.                     var name = namesArray[i];
  609.                     var isExpanded = printInspector(isNode, i, props[name].type, name, props[name].valString);
  610.  
  611.                     if (isExpanded && props[name].type[0] == "o") {
  612.                         displayRecursive(true, props[name].value);
  613.                            if (debugVerbose)
  614.                             printConsole(name+":"+props[name].valString+"\n");
  615.                     }
  616.                     isNode = false;
  617.                 }
  618.                 getParentList();
  619.             }
  620.         }
  621.     }
  622. }
  623.  
  624. function where() {
  625.     if (jsStack) {
  626.         for(var i = 0; i < jsStack.length; i++) {
  627.             var displayString = IDS_STACK_STRING.replace('%d', jsStack[i].lineno);
  628.             displayString = displayString.replace('%s', jsStack[i].script.toString());
  629.             printStack(displayString);
  630.         }
  631.     }
  632. }
  633.  
  634. function selectFrame(frameNum) {
  635.     currentFrame = frameNum;
  636.     selectScriptLine(jsStack[currentFrame].lineno, jsStack[currentFrame].script.fileName, "", frameNum);
  637. }
  638.  
  639. function debugEval(text) {
  640.     var scopeChain = jsd.GetScopeChainForStackFrame(jsStack[currentFrame].handle);
  641.     var ret;
  642.     try {
  643.         ret = jsd.EvaluateScriptInStackFrame.apply(scopeChain, [jsStack[currentFrame].handle, text]);
  644.     } catch (e) {
  645.         return e;
  646.     }
  647.  
  648.     return ret;
  649. }
  650.  
  651. function watch(i, text) {
  652.     if (jsStack && text != "") {
  653.         var ret = debugEval(text);
  654.            printWatch(i, text, ret.toString());
  655.     } else {
  656.            printWatch(i, text, IDS_CANNOT_EVALWATCH);
  657.     }
  658. }
  659.  
  660. function changeLocal(varName, value, bThis) {
  661.     if (jsStack) {
  662.         var ret = debugEval(varName + " = " + value + ";");
  663.         listRecursive(bThis);
  664.     }
  665. }
  666.  
  667. function scriptExists(fileName) {
  668.     for(var i in JSDScript.scripts) {
  669.         if (fileName == JSDScript.scripts[i].fileName)
  670.             return true;
  671.     }
  672.     return false;
  673. }
  674.  
  675. function listScriptFunctions(fileName) {
  676.     var o = new Object();
  677.     for(var i in JSDScript.scripts) {
  678.         var script = JSDScript.scripts[i];
  679.         if (script && fileName == script.fileName)
  680.             o[script.funName] = script.base;
  681.     }
  682.     for(var i in o)
  683.         printFunction(i, o[i]);
  684. }
  685.